package hikari.gui.guicomponents.new_draggable_tree;

import hikari.gui.guicomponents.easydrag.DefaultDrag;
import hikari.gui.guicomponents.easydrag.DefaultDrop;
import hikari.gui.guicomponents.easydrag.listeners.DragListener;
import hikari.gui.guicomponents.easydrag.listeners.DropListener;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DropTargetDropEvent;
import javax.swing.JComponent;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

/**
 * @author sad
 */
public class hDraggableTree extends JTree {

    public hDraggableTree(String caption) {
        super(new DefaultMutableTreeNode(caption));
        initDragDrop();
    }
    
    private void initDragDrop(){
    DefaultDrag drag = new DefaultDrag(this, new DragListener() {
            @Override
            public Object getObject(DragGestureEvent de) {
                return (TreePath) getSelectionPath();
            }
        });

        DefaultDrop drop = new DefaultDrop(this, new DropListener() {
            @Override
            public void performDrop(Component source, Component target, DropTargetDropEvent dtde, Object data) {
                putClientProperty("Ymark", null);
                if (source == target) {
                    TreePath path = getClosestPathForLocation(dtde.getLocation().x, dtde.getLocation().y);
                    TreePath movedPath = (TreePath) data;
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) movedPath.getLastPathComponent();
                    DefaultMutableTreeNode targetNode = (DefaultMutableTreeNode) path.getLastPathComponent();
                    getDefaultModel().removeNodeFromParent(node);
                    getDefaultModel().insertNodeInto(node, targetNode, targetNode.getChildCount());
                    //expandPath(path.pathByAddingChild(node));
                }

            }

            @Override
            public void dragOver(Object data, int x, int y) {
                getPathForLocation(x, y);
                int index = getClosestRowForLocation(x, y);
                Rectangle rect = getRowBounds(index);
                putClientProperty("Ymark", rect.y);
                repaint();
            }

            @Override
            public boolean canDrop(Component source, Component target, Object data, int x, int y) {
                TreePath path = getClosestPathForLocation(x, y);
                TreePath movedPath = (TreePath) data;
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) movedPath.getLastPathComponent();
                DefaultMutableTreeNode targetNode = (DefaultMutableTreeNode) path.getLastPathComponent();
                return !targetNode.isNodeAncestor(node);
            }
        });
        drag.setDragVisible(false);
        drag.setEnabled(true);
        drop.setEnabled(true);
    }

    
    
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Integer y = (Integer) getClientProperty("Ymark");
        if (y == null) {
            return;
        }
        g.drawLine(0, y, getWidth(), y);
    }

    public DefaultTreeModel getDefaultModel() {
        return (DefaultTreeModel) super.getModel();
    }
}
